package com.web_bloks.html.client;

//import com.google.gwt.xml.client.Document;
//import com.google.gwt.xml.client.Element;

import com.google.gwt.user.client.DOM;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Element;
import com.google.gwt.http.client.URL;

import com.web_bloks.system.client.Logger;

/**
 * FormHelper
 * 
 * @author Jean-Lou Dupont
 * @see http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
 * 
 */
public class FormHelper {

	private FormHelper() {
		
	}
	
	/*===================================================================
	 * PUBLIC 
	 ===================================================================*/

	public static String serialize(Element form) throws HtmlException {

		if ( form == null ) {
			throw new HtmlException( "FormHelper.serialize: element not found" );
		}

		// iterate through all child elements
		//Logger.logInfo("INPUT");
		JavaScriptObject l1 = getElementsByTagName(form, "input" );
		String s1 = processList( l1 );
		Logger.logInfo("INPUT, string:" + s1);
		
		//Logger.logInfo("SELECT");		
		JavaScriptObject l2 = getElementsByTagName(form, "select" );
		String s2 = processList( l2 );
		Logger.logInfo("SELECT, string:" + s2);
		
		//Logger.logInfo("TEXTAREA");		
		JavaScriptObject l3 = getElementsByTagName(form, "textarea" );
		String s3 = processList( l3 );
		Logger.logInfo("TEXTAREA, string:" + s3);
		
		return s1 + s2 + s3;
		
	}
	
	/**
	 * Encodes an HTML form as 'application/x-www-form-urlencoded'
	 * 
	 * @param eid Element id
	 * @return result String
	 */
	public static String serialize(String eid) 
		throws HtmlException {
		
		Element form = DOM.getElementById(eid);

		return serialize(form);
	}
	protected static String processList(JavaScriptObject list) {
		
		String result = new String();
		String iresult = null;
		
		JavaScriptObject e;
		//Logger.logDir( list );
		
		for (int i=0; i<getLength(list); i++) {
			e = getItem(list,i);
			
			//Logger.logInfo("processList: item: " + i);
			
			if ( ( getNodeAttributeString(e, "type") == "radio" ) || (getNodeAttributeString(e, "type") == "checkbox")) {
				if ( getNodeAttributeBoolean(e, "checked") != true )
					continue;
			}
		
			iresult = encodeNodeElement( e );
			if ( iresult == null )
				continue;
			
			if ( i > 0 )
				result += "&";
			
			result += iresult;
		}
		return result;
	}
	/**
	 * Encodes a DOM node element 'urlencoded'
	 * @param e
	 * @return
	 */
	public static String encodeNodeElement( JavaScriptObject e ) {
		
		String name  = getAttributeName(e);
		String value = getAttributeValue(e);
		
		//Logger.logInfo("encodeNodeElement: name: " + name );
		//Logger.logInfo("encodeNodeElement: value: " + value );
		
		if ( name.length() == 0 )
			return null;
		
		String result = new String(
				URL.encodeComponent(name) + 
				"=" +
				URL.encodeComponent( value ) );
		
		return result;
	}
	
	/*===================================================================
	 * NATIVE
	 ===================================================================*/
	public static native JavaScriptObject getElementsByTagName(Element e, String tag) /*-{
	    var elems = e.getElementsByTagName(tag);
	    return elems || null;
	}-*/;
	public static native String getNodeAttributeString( JavaScriptObject n, String attribute ) /*-{
		return n[attribute];
	}-*/;

	public static native boolean getNodeAttributeBoolean( JavaScriptObject n, String attribute ) /*-{
		return n[attribute];
	}-*/;
	
	public static native int getLength(JavaScriptObject o) /*-{
		return o.length;
	}-*/;

	public static native JavaScriptObject getItem(JavaScriptObject o, int index) /*-{
		return o.item(index);
	}-*/;
	
	public static native String getAttributeName(JavaScriptObject o) /*-{
		return o.name;
	}-*/;
	public static native String getAttributeValue(JavaScriptObject o) /*-{
		return o.value;
	}-*/;
	
}//END
